home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util4 / autoftp.lha / AutoFTP.rexx
OS/2 REXX Batch file  |  1996-01-12  |  16KB  |  478 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /* AutoFTP.rexx : an ARexx script to automatically a list of files from an   */
  4. /*                Aminet archive site.  When run, the new RECENT listing of  */
  5. /*           the site is downloaded, and GadMGet is run on that         */
  6. /*                listing.  After GadMGet is terminated, GadMGet's output is */
  7. /*                sent to ncFTP, which automatically connects to the site    */
  8. /*                and downloads the programs specified by the user.          */
  9. /*                                                                           */
  10. /* version:  1.5                                                             */
  11. /*                                                                           */
  12. /*   Don't use AutoFTP unless you have AmiTCP, GadMGet, and ncFTP already    */
  13. /*   working correctly.  AutoFTP relies on these programs to work.           */
  14. /*                                                                           */
  15. /*                                                                           */
  16. /*   Command line Switches accepted :                                        */
  17. /*          YES -- Automatically download a new RECENT file                  */
  18. /*          NO  -- Don't download a RECENT file                              */
  19. /*        DEBUG -- Write all AmigaDOS commands executed to stdout            */
  20. /*                                                                           */
  21. /*   If neither of the above is specified, a requester will be displayed     */
  22. /*   asking the user whether or not to get a new RECENT file or not.         */
  23. /*                                                                           */
  24. /*****************************************************************************/
  25.  
  26.  
  27. /**************************************************************************/
  28. /* ---------- ADJUST THESE PARAMETERS TO FIT YOUR PREFERENCES ----------- */
  29. /**************************************************************************/
  30.  
  31. /* The Aminet FTP Site you prefer to use */
  32. AminetSite = "ftp.netnet.net"
  33.  
  34. /* The root directory of Aminet within that site */
  35. AminetRootDir = "/pub/aminet"
  36.  
  37. /* The directory you want your copy of RECENT to be in */
  38. LocalRecentDir = "dh0:"            
  39.  
  40. /* Path & Filename of GadMGet executable */
  41. GadMGet = "GadMget" 
  42.  
  43. /* Path & Filename of ncFTP executable */
  44. ncFTP = "amitcp:bin/ncFTP"
  45.  
  46. /* Any miscellaneous startup arguments you wish to be included 
  47.    on GadMGet's command line call.  See GadMGet documentation on
  48.    "Startup Options" for a list of possible options. */
  49. GadMGetArgs = ""  
  50.  
  51. /* The directory path you want AutoFTP to download files to. */
  52. DownloadDir = "ram:"
  53.  
  54. /* Do you want AutoFTP to keep saved selected lines from previous 
  55.    GadMget sessions? */
  56. PreserveSelected = YES
  57.  
  58. /* Do you want AutoFTP to remove lines from the new RECENT file that you
  59.    already have selected in the old RECENT file?  (This option is only
  60.    significant if PreserveSelected is YES) */
  61. DoPruning = YES
  62.  
  63. /* Do you want AutoFTP to add the comment lines from the RECENT file
  64.    to the downloaded files, as FileNotes? */
  65. AddFileNotes = YES
  66.  
  67. /* Template string for FileNotes.  $GADMGETDIR, $GADMGETFILE, and 
  68.    $GADMGETCOMMENT are avaiable keywords that will be replaced by 
  69.    their respective values in the FileNotes. */
  70. FileNoteFormatString = "$GADMGETDIR $GADMGETFILE [$GADMGETCOMMENT]"
  71.  
  72. /* If set to non-zero, each of these will ensure that its related
  73.    field in the FileNotes is the length specified. */
  74. GadMgetDirLength  = 13
  75. GadMgetFileLength = 18
  76. GadMgetCommLength = 40
  77.  
  78.  
  79.  
  80. /**************************************************************************/
  81. /* ------- END USER PARAMETERS --- DO NOT MODIFY BELOW THIS LINE -------- */
  82. /**************************************************************************/
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102. /**************************************************************************/
  103. /* ---------------------- BEGIN AUTOFTP SCRIPT CODE --------------------- */
  104. /**************************************************************************/
  105.  
  106. options results
  107. parse arg CommandLineArg
  108.  
  109. DownloadRECENT = MAYBE
  110. Debug = FALSE
  111.  
  112. CommandLineArg = upper(CommandLineArg)
  113.  
  114. if (CommandLineArg == "?") then do 
  115.     say "AutoFTP:  AutoFTP YES/S NO/S DEBUG/S" 
  116.     exit
  117.     end
  118. if (CommandLineArg == "YES") then DownloadRECENT = YES
  119. if (CommandLineArg == "NO")  then DownloadRECENT = NO
  120. if (CommandLineArg == "DEBUG") then do
  121.     say "AutoFTP:  Debug mode on."
  122.     Debug = TRUE
  123.     end        
  124.  
  125. if (DownloadRECENT == MAYBE) then do
  126.     /* Load rexxreqtools.library if possible */
  127.     if (show('L','rexxreqtools.library')) then RexxReqToolsLoaded = 1
  128.         else RexxReqToolsLoaded = addlib('rexxreqtools.library',0,-30)
  129.     
  130.     if (RexxReqToolsLoaded) then UserResponse = rtezrequest('Shall I download the new RECENT file now?',"_Yes|_No")
  131.        else do
  132.            say "[Warning: rexxreqtools.library not available!]"
  133.            say "Shall I download a new RECENT file now?  (y/n)"
  134.            pull UserResponse
  135.            UserString = upper(UserResponse)
  136.            UserResponse = 1
  137.            if (left(UserString,1) == "N") then UserResponse = 0
  138.        end
  139.         
  140.     if (UserResponse == 1) then DownloadRECENT = YES 
  141.                    else DownloadRECENT = NO
  142.     end
  143.  
  144.  
  145. /* Fix up the syntax of some parameters */
  146. if (right(AminetSite,1) ~= ":") then    AminetSite    = AminetSite    || ":"
  147. if (right(AminetRootDir,1) ~= "/") then AminetRootDir = AminetRootDir || "/"
  148.  
  149. /* Get a nice temporary filename or two */
  150. ProcessID = time('S')
  151. TempFile = "t:AutoFTP.temp." || ProcessID
  152. BackupFile = "t:AutoFTP.script.bak"
  153. TempRecent = "t:AutoFTP.RECENT." || ProcessID
  154.  
  155. GadMGetArgs = GadMGetArgs || " NOSIMPLEPATHS AMINETPATH " || AminetRootDir || " OUTPUT " || TempFile
  156. LocalRecentFile = LocalRecentDir || "RECENT"
  157.  
  158. if (DownloadRECENT == YES) then do
  159.     /* Construct request for RECENT */
  160.     RECENTfile = AminetSite || AminetRootDir || "RECENT"
  161.  
  162.     say "Retrieving the current RECENT file from " || AminetSite
  163.     GetRECENTCommand = ncFTP || " -r " || RECENTfile
  164.  
  165.     /* Get RECENT file */
  166.     call Pragma('D',"t:")
  167.     success = DoCommand(GetRECENTCommand)
  168.     RenameCommand = "rename RECENT " || TempRecent || " QUIET"
  169.     success = DoCommand(RenameCommand)
  170.     call Pragma('D',LocalRECENTdir)
  171.  
  172.     /* Now either process the downloaded RECENT file to save selected lines,
  173.        or if that's turned off, just copy it over. */
  174.     if (PreserveSelected = YES) then do
  175.         success = SmartCopy(LocalRecentFile,TempRecent,LocalRecentFile)
  176.         if (success == 0) then do
  177.             say "WARNING:  File Merge failed.  Falling back to simple copy"
  178.             CopyCommand = "copy " || TempRecent || " " || LocalRecentFile || " QUIET"
  179.             success = doCommand(CopyCommand)
  180.             end    
  181.         end
  182.     else do
  183.         CopyCommand = "copy " || TempRecent || " " || LocalRecentFile || " QUIET"
  184.         success = doCommand(CopyCommand)
  185.         end
  186.  
  187.     DeleteTempRecentCommand = "delete " || TempRecent || " QUIET"
  188.     success = DoCommand(DeleteTempRecentCommand)    
  189.     end
  190.     
  191. /* Now we run GadMGet */
  192. GadMGetCommand = GadMGet || " " || LocalRecentFile || " " || GadMGetArgs
  193. success = DoCommand(GadMGetCommand)
  194.  
  195. /* Make sure that the output file is there */
  196. if (~Exists(TempFile)) then do
  197.     say "You didn't select any files.  Exiting..."
  198.     exit
  199.     end
  200.     
  201.     
  202. /* Make a backup copy of GadMGet's output, that way if the ftp session
  203.    breaks, at least the user still has the last output to use manually
  204.    is s/he wants. */
  205. BackupCommand = 'copy ' || TempFile || " " || BackupFile || " QUIET"
  206. success = DoCommand(BackupCommand)
  207.  
  208. /* Let the user see the list... */
  209. say "------FTP script is as follows-----"
  210. address COMMAND "type " TempFile
  211. say "-----------End FTP script----------"
  212.  
  213. /* Get the current time, in case we need it for later */
  214.  
  215.  
  216. /* Change to the directory the user wishes to download to */
  217. call Pragma('D',DownloadDir)
  218. DownloadCommand = ncFTP || " -r " || AminetSite || AminetRootDir || " <" || TempFile
  219. success = DoCommand(DownloadCommand)
  220.  
  221. /* If the user wants filenotes added, here's where we do it! */
  222. if (AddFileNotes = YES) then call AddFileNotes(LocalRecentFile, TempFile, DownloadDir, FileNoteFormatString, GadMgetDirLength, GadMgetFileLength, GadmgetCommLength)
  223.  
  224. /* Now delete the Temporary file */
  225. DeleteCommand = "delete " || TempFile || " QUIET"
  226. success = DoCommand(DeleteCommand)
  227.  
  228. say "AutoFTP script terminating."
  229. exit
  230.  
  231.  
  232.  
  233.  
  234. /**************************************************************************/
  235. /* ------------------------ BEGIN PROCEDURES ---------------------------- */
  236. /**************************************************************************/
  237.  
  238.  
  239.  
  240.  
  241.  
  242. /* Executes an AmigaDos shell command for us, giving output if called for. */
  243. DoCommand: procedure expose Debug
  244.     parse arg thiscommand
  245.         
  246.     if (Debug == TRUE) then say "EXECUTING: [" || thiscommand || "]"    
  247.     address COMMAND thiscommand
  248.     return 1
  249.  
  250.  
  251.  
  252.  
  253.  
  254. /* Loads in the given RECENT file and CommandFile, and if a filename
  255.    is both in the CommandFile and the ScanDir, sets its FileNote
  256.    to the comment given in the RECENT file.  Any string in the 
  257.    FormatString will be prepended to the the FileNote, with the keyword
  258.    tokens listed below replaced by what they represent. */
  259. AddFileNotes: procedure expose Debug
  260.     parse arg RecentFile, CommandFile, ScanDir, NoteExpr, DirLen, FileLen, CommLen
  261.     
  262.     /* Things to replace */
  263.     DirToken  = "$GADMGETDIR"
  264.     FileToken = "$GADMGETFILE"
  265.     CommToken = "$GADMGETCOMMENT"
  266.     
  267.     /* Keep for later, if we need to replace $DIR */
  268.     OriginalPreamble = NoteExpr
  269.     
  270.     /* First thing we must do:  parse the CommandFile */
  271.     if ~open(CommandInput,  CommandFile,  'R') then do
  272.         say "AddFileNotes: Couldn't open temp file ["|| CommandFile|| "]!"
  273.         return 0
  274.         end
  275.     
  276.     /* Now go through, and get a database of names and dirs */
  277.     RequestedFileIndex = 0
  278.           do until eof(CommandInput)
  279.             ThisLine = readln(CommandInput)
  280.             RequestedFileIndex = ParseGetLine(ThisLine, RequestedFileIndex)
  281.         end 
  282.     call close(CommandInput)
  283.     
  284.  
  285.     /* Next thing we must do:  read the RecentFile */
  286.     if ~open(RecentInput,  RecentFile,  'R') then do
  287.         say "AddFileNotes: Couldn't open temp file ["|| RecentFile|| "]!"
  288.         return 0
  289.         end
  290.     
  291.     /* Now go through, and get a database of names and dirs */
  292.     RecentFileIndex = 0    
  293.           do until eof(RecentInput)
  294.             ThisLine = readln(RecentInput)
  295.  
  296.         /* Get data from line */
  297.         parse var ThisLine ThisName ThisDir Comment
  298.  
  299.         Comment = ExtractComment(Comment)
  300.         
  301.         /* Scan thru all of our entries, looking for a match */
  302.         do TempReqIndex = 0 to (RequestedFileIndex-1)
  303.             if ((Files.TempReqIndex.File == ThisName)&(Files.TempReqIndex.Dir == ThisDir)) then Files.TempReqIndex.Comm = Comment
  304.             end
  305.         end 
  306.     call close(RecentInput)
  307.     
  308.     /* Now any and all comments should be filled out... so do the SetFileNote thingy */
  309.     do TempReqIndex = 0 to (RequestedFileIndex-1)
  310.         Note = NoteExpr
  311.         
  312.         Dirx  = Files.TempReqIndex.Dir  
  313.         Filex = Files.TempReqIndex.File
  314.         Commx = Files.TempReqIndex.Comm
  315.         
  316.         /* pad/cut as necessary */        
  317.         if (DirLen > 0)  then Dirx  = substr(Dirx,  1, DirLen)
  318.         if (FileLen > 0) then Filex = substr(Filex, 1, FileLen)
  319.         if (CommLen > 0) then Commx = substr(Commx, 1, CommLen)
  320.         
  321.         /* First, make up the filenote string */
  322.         do while (Index(Note,DirToken) > 0)
  323.             Note = SubstituteString(Note,DirToken,Dirx)
  324.             end
  325.         do while (Index(Note,FileToken) > 0)
  326.             Note = SubstituteString(Note,FileToken,Filex)
  327.             end
  328.         do while (Index(Note,CommToken) > 0)
  329.             Note = SubstituteString(Note,CommToken,Commx)
  330.             end
  331.         /* Now set it */
  332.         if (exists(Files.TempReqIndex.File) == 1) then call DoCommand("FileNote " || Files.TempReqIndex.File || ' "' || Note || '"') 
  333.                               else say "SetFileNote:  Warning, couldn't find file [" || Files.TempReqIndex.File || "]"
  334.  
  335.         end
  336.     return 1
  337.  
  338.  
  339. /* Replaces the first ReplaceMe with WithMe in the string Line */    
  340. SubstituteString: procedure expose Debug
  341.     parse arg Line, ReplaceMe, WithMe
  342.  
  343.     /* Sanity check--avoid infinite loops */
  344.     if (Index(WithMe,ReplaceMe) > 0) then return Line
  345.     
  346.     StartOfVictim = Index(Line, ReplaceMe)
  347.     LengthOfVictim = length(ReplaceMe)
  348.     
  349.     Line = DelStr(Line, StartOfVictim, LengthOfVictim)
  350.     Line = Insert(WithMe, Line, StartOfVictim-1)
  351.     return Line
  352.     
  353.     
  354. /* Removes the size info and the "+" from the remainder of the line */
  355. ExtractComment: procedure expose Debug
  356.     parse arg Line
  357.     
  358.     Line = Strip(Line)
  359.         
  360.     /* Basically, if the first word has a '+', return starting
  361.          after the +, else return starting with the second word */
  362.       FirstWord = left(Line,WordLength(Line,1))
  363.       
  364.       PlusPos = Index(FirstWord,"+")
  365.       if (PlusPos > 0) then Line = right(Line,length(Line)-PlusPos)
  366.                  else Line = right(Line,length(Line)-WordIndex(Line,2))
  367.       return Line
  368.       
  369.     
  370. /* Parses one line of the Command file.  Returns the new index to use
  371.    for next time (i.e. the next "fresh" one. */
  372. ParseGetLine: procedure expose Debug Files.
  373.     parse arg Line, FIndex
  374.         
  375.     do while (length(Line) > 0)
  376.         /* Remove any leading or trailing spaces */
  377.         Line = Strip(Line)
  378.         
  379.         /* Length of the first word in the line */
  380.         FirstWordLength = WordLength(Line, 1)
  381.         
  382.         /* Get the first "word" in the line */
  383.         NextWord = left(Line,FirstWordLength)
  384.  
  385.         /* Remove it from the line */
  386.         Line = right(Line, Length(Line) - FirstWordLength)
  387.         
  388.         /* Assume that if it's a file, it will have '/' separator */
  389.         LastSlash = LastPos("/",NextWord)
  390.         if ((LastSlash > 0)&(NextWord ~= "../..")) then do
  391.             Files.FIndex.Dir = left(NextWord,LastSlash-1)
  392.             Files.FIndex.File = right(NextWord,FirstWordLength-LastSlash)
  393.             FIndex = FIndex + 1
  394.             end
  395.             
  396.         end
  397.     return FIndex
  398.     
  399.     
  400.  
  401. /* Looks at the current RECENT and the new one, and merges them so that: 
  402.     1) All currently selected lines in the current RECENT are in the
  403.        output file's selected section
  404.     2) All currently selected lines in the current RECENT are NOT in
  405.        the output file's selectable section.   */
  406. SmartCopy: procedure expose Debug DoPruning
  407.     parse arg OldRecent, NewRecent, OutFile .
  408.  
  409.     if (Debug == TRUE) then say "Merging " || OldRecent || " and " || NewRecent || " into " || Outfile
  410.  
  411.     /* This needs to be accurate! */
  412.     BOOKMARK = "| --- GadMGet: Begin Selected Files --- "
  413.     
  414.     /* Load OldRecent into OldRecentSel  */
  415.     OSelIndex = 0
  416.     OKeepInput = 0
  417.     if ~open(OldInput,  OldRecent,  'R') then return 0
  418.           do until eof(OldInput)
  419.             ThisLine = readln(OldInput)
  420.             if (ThisLine == BOOKMARK) then do
  421.                 OKeepInput = 1
  422.                 end
  423.             else do
  424.                 if (OKeepInput == 1) then do
  425.                     OldRecentSel.OSelIndex = ThisLine
  426.                     OSelIndex = OSelIndex + 1
  427.                 end
  428.             end    
  429.         end 
  430.     call close(OldInput)
  431.  
  432.     if (OSelIndex == 0) then do
  433.         /* No selected lines to save.  Might as well take the short cut */
  434.         CopyCommand = "copy " || NewRecent || " " || OutFile
  435.         success = DoCommand(CopyCommand)
  436.         return 1
  437.         end
  438.     
  439.     /* Load NewRecent into NewRecent.Reg.  Presumably since we just
  440.        downloaded this from Aminet, there won't be a NewRecent.Sel ! */
  441.     NewRecentRegIndex = 0
  442.     if ~open(NewInput, NewRecent, 'R') then return 0
  443.     if ~open(NewOutput,OutFile,   'W') then do
  444.         call close(NewInput)
  445.         return 0
  446.         end
  447.           do until eof(NewInput)
  448.             ThisLine = readln(NewInput)
  449.         CheckIndex = 0
  450.         OKToPrint = 1
  451.         if (DoPruning == YES) then do
  452.             do while ((CheckIndex < OSelIndex)&(OKToPrint = 1))
  453.                 if (OldRecentSel.CheckIndex == ThisLine) then OKToPrint = 0
  454.                 CheckIndex = CheckIndex + 1
  455.                 end
  456.             end
  457.         if (OKToPrint == 1) then call writeln(NewOutput,ThisLine)
  458.         end 
  459.     call close(NewInput)
  460.     
  461.     /* Now write the bookmark, and our selected files */
  462.     call writeln(NewOutput,BOOKMARK)
  463.     WriteIndex = 0
  464.     do while (WriteIndex < OSelIndex)
  465.         call writeln(NewOutput,OldRecentSel.WriteIndex)
  466.         WriteIndex = WriteIndex + 1
  467.         end
  468.     call close(NewOutput)
  469.     return 1    
  470.     
  471.  
  472.  
  473.  
  474.  
  475. /**************************************************************************/
  476. /* ------------------------ END AUTOFTP SCRIPT CODE --------------------- */
  477. /**************************************************************************/
  478.